package org.budo.gitee.webhook;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.budo.support.lang.util.StringUtil;
import org.budo.support.mvcs.Mvcs;
import org.budo.support.servlet.util.ResponseUtil;
import org.budo.time.Time;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

/**
 * @author limingwei
 */
@Slf4j
public class GiteeWebHookFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("#21 request=" + request);

        Map<String, String[]> requestHeaderMap = Mvcs.getRequestHeaderMap(request);
        log.info("#31 requestHeaderMap=" + requestHeaderMap);

        String requestBody = Mvcs.getRequestBody(request);
        log.info("#34 requestBody=" + requestBody);

        JSONObject requestJson = JSON.parseObject(requestBody);
        JSONArray commits = requestJson.getJSONArray("commits");
        if (null != commits && !commits.isEmpty()) {
            PushCommit pushCommit = this.pushCommit(requestJson);
            this.handlePushCommit(pushCommit);

            ResponseUtil.writeToResponse(response, Time.now().toString("yyyyMMdd.HHmmss.SSS"));
            return;
        }

        String action = requestJson.getString("action");
        if ("comment".equals(action)) {
            CommentIssue commentIssue = this.commentIssue(requestJson);
            this.handleCommentIssue(commentIssue);

            ResponseUtil.writeToResponse(response, Time.now().toString("yyyyMMdd.HHmmss.SSS"));
            return;
        }

        JSONObject issue = requestJson.getJSONObject("issue");
        if (null != issue && !issue.isEmpty()) {
            OpenIssue openIssue = this.openIssue(requestJson);
            this.handleOpenIssue(openIssue);

            ResponseUtil.writeToResponse(response, Time.now().toString("yyyyMMdd.HHmmss.SSS"));
            return;
        }

        ResponseUtil.writeToResponse(response, Time.now().toString("yyyyMMdd.HHmmss.SSS"));
    }

    protected void handleOpenIssue(OpenIssue openIssue) {
        log.info("#57 handleOpenIssue, openIssue=" + openIssue);
    }

    protected void handlePushCommit(PushCommit pushCommit) {
        log.info("#61 handlePushCommit, pushCommit=" + pushCommit);
    }

    protected void handleCommentIssue(CommentIssue commentIssue) {
        log.info("#61 handleCommentIssue, commentIssue=" + commentIssue);
    }

    private CommentIssue commentIssue(JSONObject requestJson) {
        JSONObject comment = requestJson.getJSONObject("comment");
        String body = comment.getString("body");

        JSONObject user = comment.getJSONObject("user");
        String name = user.getString("name");

        JSONObject issue = requestJson.getJSONObject("issue");
        String title = issue.getString("title");

        CommentIssue commentIssue = new CommentIssue();
        commentIssue.setUserName(name);
        commentIssue.setIssueTitle(title);
        commentIssue.setCommentBody(body);
        return commentIssue;
    }

    private OpenIssue openIssue(JSONObject requestJson) {
        OpenIssue openIssue = new OpenIssue();

        JSONObject user = requestJson.getJSONObject("user");
        openIssue.setUserName(user.getString("name"));
        openIssue.setUserUrl(user.getString("url"));

        JSONObject project = requestJson.getJSONObject("project");
        openIssue.setProjectName(project.getString("name"));
        openIssue.setProjectUrl(project.getString("url"));

        openIssue.setIssueTitle(requestJson.getString("title"));
        openIssue.setIssueUrl(requestJson.getString("url"));

        return openIssue;
    }

    private PushCommit pushCommit(JSONObject jsonObject) {
        PushCommit pushCommit = new PushCommit();

        JSONObject user = jsonObject.getJSONObject("user");
        pushCommit.setUserName(user.getString("name"));
        pushCommit.setUserUrl(user.getString("url"));

        JSONObject project = jsonObject.getJSONObject("project");
        pushCommit.setProjectName(project.getString("name"));
        pushCommit.setProjectUrl(project.getString("url"));

        JSONArray commits = jsonObject.getJSONArray("commits");
        if (null == commits) {
            return pushCommit;
        }

        pushCommit.setCommits(new ArrayList<String>());
        for (Object _each : commits) {
            JSONObject each = (JSONObject) _each;
            String msg = each.getString("message");
            if (StringUtil.isEmpty(msg)) {
                pushCommit.getCommits().add("commit message 为空[1]");
            }

            String replace = msg.replace("\"", "");
            if (StringUtil.isEmpty(replace)) {
                pushCommit.getCommits().add("commit message 为空[2]");
            }

            pushCommit.getCommits().add(replace);
        }

        return pushCommit;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("#21 init, this=" + this);
    }

    @Override
    public void destroy() {
        log.info("#29 destroy, this=" + this);
    }
}